home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / mush5.7 / part12 < prev    next >
Encoding:
Internet Message Format  |  1987-09-19  |  50.5 KB

  1. Subject:  v11i062:  Mail user's shell, Part12/12
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: island!argv@Sun.COM (Dan Heller)
  7. Posting-number: Volume 11, Issue 62
  8. Archive-name: mush5.7/Part12
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 12 (of 12)."
  17. # Contents:  bind.c doproc.c init.c viewopts.c
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'bind.c' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'bind.c'\"
  21. else
  22. echo shar: Extracting \"'bind.c'\" \(11484 characters\)
  23. sed "s/^X//" >'bind.c' <<'END_OF_FILE'
  24. X/* bind.c */
  25. X
  26. X#ifdef CURSES
  27. X
  28. X#include "bindings.h"
  29. X#include "mush.h"
  30. X
  31. X#define MAX_BIND_LEN 20   /* max length a string can be to bind to a command */
  32. X
  33. Xstruct cmd_map {
  34. X    int m_cmd;  /* the command this is mapped to  */
  35. X    char *m_str;  /* the string user types (cbreak) */
  36. X    struct cmd_map *m_next;
  37. X} *cmd_map;
  38. X
  39. Xinit_bindings()
  40. X{
  41. X    add_bind("g", 1);
  42. X    add_bind("w", 2);
  43. X    add_bind("W", 3);
  44. X    add_bind("s", 4);
  45. X    add_bind("S", 5);
  46. X    add_bind("c", 6);
  47. X    add_bind("C", 7);
  48. X    add_bind("d", 8);
  49. X    add_bind("D", 9);
  50. X    add_bind("u", 10);
  51. X    add_bind("U", 11);
  52. X    add_bind("\\CR", 12);
  53. X    add_bind("\\CL", 13);
  54. X    add_bind("j", 14), add_bind("J", 14), add_bind("\\n", 14), add_bind("+",14);
  55. X    add_bind("k", 15), add_bind("K", 15), add_bind("-",15), add_bind("\\CK",15);
  56. X    add_bind("^", 16);
  57. X    add_bind("$", 17);
  58. X    add_bind("{", 18);
  59. X    add_bind("}", 19);
  60. X    add_bind("z", 20);
  61. X    add_bind("Z", 21);
  62. X    add_bind("H", 22);
  63. X    add_bind("(", 23);
  64. X    add_bind(")", 24);
  65. X    add_bind("/", 25);
  66. X    add_bind("\\C_", 26);  /* this is really ^/ */
  67. X    add_bind("\\CN", 27);
  68. X    add_bind("\\CP", 28);
  69. X    add_bind("o" ,29);
  70. X    add_bind("O", 30);
  71. X    add_bind("Q", 31);
  72. X    add_bind("q", 32);
  73. X    add_bind("X", 33);
  74. X    add_bind("x", 34);
  75. X    add_bind("\\CU", 35);
  76. X    add_bind("f", 36);
  77. X    add_bind("!", 37);
  78. X    add_bind(":", 38);
  79. X    add_bind("|", 39);
  80. X    add_bind("%", 40);
  81. X    add_bind("v", 41);
  82. X    add_bind("i", 42);
  83. X    add_bind("a", 43);
  84. X    add_bind("h", 44);
  85. X    add_bind("V", 45);
  86. X    add_bind("M", 46);
  87. X    add_bind("m", 47);
  88. X    add_bind("r", 48);
  89. X    add_bind("R", 49);
  90. X    add_bind("t", 50), add_bind(".", 50), add_bind("p", 50);
  91. X    add_bind("T", 51);
  92. X    add_bind("n", 52);
  93. X    add_bind("b", 53);
  94. X    add_bind("B", 54);
  95. X    add_bind("?", 55); /* C_HELP Must be the last one! */
  96. X}
  97. X
  98. Xstruct cmd_map map_func_names[] = {
  99. X    { C_NULL,        NULL,            NULL_MAP },
  100. X    { C_GOTO_MSG,    "goto msg",        NULL_MAP },
  101. X    { C_WRITE_MSG,    "write",        NULL_MAP },
  102. X    { C_WRITE_LIST,    "write list",        NULL_MAP },
  103. X    { C_SAVE_MSG,    "save",            NULL_MAP },
  104. X    { C_SAVE_LIST,    "save list",        NULL_MAP },
  105. X    { C_COPY_MSG,    "copy",            NULL_MAP },
  106. X    { C_COPY_LIST,    "copy list",        NULL_MAP },
  107. X    { C_DELETE_MSG,    "delete",        NULL_MAP },
  108. X    { C_DELETE_LIST,    "delete list",        NULL_MAP },
  109. X    { C_UNDEL_MSG,    "undelete",        NULL_MAP },
  110. X    { C_UNDEL_LIST,    "undelete list",    NULL_MAP },
  111. X    { C_REVERSE,    "reverse video",    NULL_MAP },
  112. X    { C_REDRAW,        "redraw",        NULL_MAP },
  113. X    { C_NEXT_MSG,    "next msg",        NULL_MAP },
  114. X    { C_PREV_MSG,    "back msg",        NULL_MAP },
  115. X    { C_FIRST_MSG,    "first msg",        NULL_MAP },
  116. X    { C_LAST_MSG,    "last msg",        NULL_MAP },
  117. X    { C_TOP_PAGE,    "top page",        NULL_MAP },
  118. X    { C_BOTTOM_PAGE,    "bottom page",        NULL_MAP },
  119. X    { C_NEXT_SCREEN,    "screen next",        NULL_MAP },
  120. X    { C_PREV_SCREEN,    "screen back",        NULL_MAP },
  121. X    { C_SHOW_HDR,    "show hdr",        NULL_MAP },
  122. X    { C_SOURCE,        "source",        NULL_MAP },
  123. X    { C_SAVEOPTS,    "saveopts",        NULL_MAP },
  124. X    { C_NEXT_SEARCH,    "search up",        NULL_MAP },
  125. X    { C_PREV_SEARCH,    "search down",        NULL_MAP },
  126. X    { C_CONT_SEARCH,    "search cont",        NULL_MAP },
  127. X    { C_PRESERVE,    "preserve",        NULL_MAP },
  128. X    { C_SORT,        "sort",            NULL_MAP },
  129. X    { C_REV_SORT,    "sort reverse",        NULL_MAP },
  130. X    { C_QUIT_HARD,    "quit!",        NULL_MAP },
  131. X    { C_QUIT,        "quit",            NULL_MAP },
  132. X    { C_EXIT_HARD,    "exit!",        NULL_MAP },
  133. X    { C_EXIT,        "exit",            NULL_MAP },
  134. X    { C_UPDATE,        "update",        NULL_MAP },
  135. X    { C_FOLDER,        "folder",        NULL_MAP },
  136. X    { C_SHELL_ESC,    "shell escape",        NULL_MAP },
  137. X    { C_CURSES_ESC,    "line mode",        NULL_MAP },
  138. X    { C_PRINT_MSG,    "lpr",            NULL_MAP },
  139. X    { C_CHDIR,        "chdir",        NULL_MAP },
  140. X    { C_VAR_SET,    "variable",        NULL_MAP },
  141. X    { C_IGNORE,        "ignore",        NULL_MAP },
  142. X    { C_ALIAS,        "alias",        NULL_MAP },
  143. X    { C_OWN_HDR,    "my hdrs",        NULL_MAP },
  144. X    { C_VERSION,    "version",        NULL_MAP },
  145. X    { C_MAIL_FLAGS,    "mail flags",        NULL_MAP },
  146. X    { C_MAIL,        "mail",            NULL_MAP },
  147. X    { C_REPLY_SENDER,    "reply",        NULL_MAP },
  148. X    { C_REPLY_ALL,    "reply all",        NULL_MAP },
  149. X    { C_DISPLAY_MSG,    "display",        NULL_MAP },
  150. X    { C_TOP_MSG,    "top",            NULL_MAP },
  151. X    { C_DISPLAY_NEXT,    "display next",        NULL_MAP },
  152. X    { C_BIND,        "bind",            NULL_MAP },
  153. X    { C_UNBIND,        "unbind",        NULL_MAP },
  154. X    { C_HELP,        "help",            NULL_MAP }
  155. X};
  156. X
  157. Xgetcmd()
  158. X{
  159. X    char         buf[MAX_BIND_LEN];
  160. X    register int     c, m, match;
  161. X    register char    *p = buf;
  162. X    register struct cmd_map *list;
  163. X
  164. X    bzero(buf, MAX_BIND_LEN);
  165. X    c = getchar();
  166. X    if (isdigit(c)) {
  167. X    (void) ungetc(c, stdin);
  168. X    return C_GOTO_MSG;
  169. X    }
  170. X    for (;; p += strlen(p), c = getchar()) {
  171. X    if (c == ESC)
  172. X        (void) strcpy(buf, "\\E");
  173. X    else if (c == '\n' || c == '\r')
  174. X        (void) strcpy(p, "\\n");
  175. X    else if (c == '\t')
  176. X        (void) strcpy(p, "\\t");
  177. X    else if (iscntrl(c))
  178. X        (void) sprintf(p, "\\C%c", upper(unctrl(c)[1]));
  179. X    else
  180. X        *p = c;
  181. X    m = 0;
  182. X    for (list = cmd_map; list; list = list->m_next)
  183. X        if ((match = prefix(buf, list->m_str)) == MATCH) {
  184. X        if (debug)
  185. X            print("\"%s\" ", map_func_names[list->m_cmd].m_str);
  186. X        return list->m_cmd;
  187. X        } else if (match != NO_MATCH)
  188. X        m++;
  189. X    if (m == 0) {
  190. X        if (debug)
  191. X        print("No binding for \"%s\" found.", buf);
  192. X        return 0;
  193. X    }
  194. X    }
  195. X}
  196. X
  197. X/*
  198. X * bind chars or strings to commands -- doesn't touch messages; return -1
  199. X * for curses mode, return -2 to have curses command set cntd_cmd to
  200. X * prevent screen refresh to allow user to read output in case of multilines.
  201. X */
  202. Xbind_it(len, argv)
  203. Xchar **argv;
  204. X{
  205. X    char buf[MAX_BIND_LEN], buf2[30];
  206. X    register int x;
  207. X    int (*oldint)(), (*oldquit)();
  208. X    int unbind = (argv && **argv == 'u');
  209. X    int ret = -1; /* return value */
  210. X
  211. X    if (istool > 1 || argv && *++argv && !strcmp(*argv, "-?"))
  212. X    return help(0, "bind", cmd_help) - 1;
  213. X
  214. X    on_intr();
  215. X
  216. X    if (unbind) {
  217. X    if (!*argv) {
  218. X        print("Unbind what? ");
  219. X        if (Getstr(buf, MAX_BIND_LEN-1, 0) <= 0) {
  220. X        off_intr();
  221. X        return -1;
  222. X        }
  223. X    } else
  224. X        (void) strcpy(buf, *argv);
  225. X    if (!un_bind(buf))
  226. X        print("\"%s\" isn't bound to a command.\n", buf);
  227. X    off_intr();
  228. X    return -1;
  229. X    }
  230. X    if (argv && *argv) {
  231. X    (void) strncpy(buf, *argv, MAX_BIND_LEN-1);
  232. X    if (!argv[1]) {
  233. X        int binding = c_bind(*argv);
  234. X        if (binding)
  235. X        print("\"%s\" is bound to \"%s\".\n",
  236. X            *argv, map_func_names[binding].m_str);
  237. X        else
  238. X        print("\"%s\" isn't bound to a command.\n", *argv);
  239. X        off_intr();
  240. X        return -1;
  241. X    } else
  242. X        argv++;
  243. X    } else {
  244. X    print("bind [<CR>=all, -?=help]: ");
  245. X    if ((len = Getstr(buf, MAX_BIND_LEN-1, 0)) == 0) {
  246. X        if (iscurses)
  247. X        putchar('\n');
  248. X        (void) c_bind(NULL);
  249. X        off_intr();
  250. X        return -2;
  251. X    }
  252. X    if (len < 0) {
  253. X        off_intr();
  254. X        return -1;
  255. X    }
  256. X    }
  257. X    /* if a binding was given on the command line */
  258. X    if (argv && *argv)
  259. X    (void) argv_to_string(buf2, argv);
  260. X    else {
  261. X    int binding;
  262. X    
  263. X    if (!strcmp(buf, "-?")) {
  264. X        if (iscurses)
  265. X        clr_bot_line();
  266. X        (void) help(0, "bind", cmd_help);
  267. X        off_intr();
  268. X        return -2;
  269. X    }
  270. X
  271. X    binding = c_bind(buf);
  272. X
  273. X    for (len = 0; len == 0; ) {
  274. X        print("\"%s\" = <%s>: New function [<CR> for list]: ",
  275. X        buf, (binding? map_func_names[binding].m_str : "unset"));
  276. X        len = Getstr(buf2, 29, 0);
  277. X        if (iscurses)
  278. X        clr_bot_line();
  279. X        if (len == 0) {
  280. X        char *maps[C_HELP+1], *p, *malloc();
  281. X        int n = 0;
  282. X
  283. X        if (iscurses)
  284. X            putchar('\n');
  285. X        for (x = 0; x < C_HELP; x++) {
  286. X            if (!(x % 4))
  287. X            if (!(p = maps[n++] = malloc(81))) {
  288. X                error("malloc in bind()");
  289. X                free_vec(maps);
  290. X                off_intr();
  291. X                return -1;
  292. X            }
  293. X            p += strlen(sprintf(p, "%-18.18s  ",
  294. X                    map_func_names[x+1].m_str));
  295. X        }
  296. X        maps[n] = NULL;
  297. X        (void) help(0, maps, NULL);
  298. X        free_vec(maps);
  299. X        ret--;
  300. X        }
  301. X    }
  302. X    /* if list was printed, ret < -1 -- tells cntd_cmd to be set and
  303. X     * prevents screen from being refreshed (lets user read output
  304. X     */
  305. X    if (len == -1) {
  306. X        off_intr();
  307. X        return ret;
  308. X    }
  309. X    }
  310. X    for (x = 1; x <= C_HELP; x++)
  311. X    if (!strcmp(buf2, map_func_names[x].m_str)) {
  312. X        int add_to_ret;
  313. X        if (debug)
  314. X        print("\"%s\" will execute \"%s\".\n", buf, buf2);
  315. X        add_to_ret = do_bind(buf, map_func_names[x].m_cmd);
  316. X        /* if do_bind hda no errors, it returned -1.  If we already
  317. X         * messed up the screen, then ret is less than -1.  return the
  318. X         * lesser of the two to make sure that cntd_cmd gets set right
  319. X         */
  320. X        off_intr();
  321. X        return min(add_to_ret, ret);
  322. X    }
  323. X    print("\"%s\": Unknown function.\n", buf2);
  324. X    off_intr();
  325. X    return ret;
  326. X}
  327. X
  328. X/*
  329. X * print current key to command bindings if "str" is NULL.
  330. X * else return the integer "m_cmd" which the str is bound to.
  331. X */
  332. Xc_bind(str)
  333. Xregister char *str;
  334. X{
  335. X    register struct cmd_map *opts;
  336. X    register int    incurses = iscurses;
  337. X    register FILE   *pp = NULL_FILE;
  338. X
  339. X    if (!str && !istool) {
  340. X    echo_on();
  341. X    if (!(pp = popen(pager, "w")))
  342. X        error(pager);
  343. X    else if (incurses)
  344. X        clr_bot_line(), iscurses = FALSE;
  345. X    turnon(glob_flags, IGN_SIGS);
  346. X    if (pp)
  347. X        fprintf(pp, "Current key to command bindings:\n\n");
  348. X    else
  349. X        wprint("Current key to command bindings:\n\n");
  350. X    }
  351. X
  352. X    for (opts = cmd_map; opts; opts = opts->m_next)
  353. X    if (!str)
  354. X        if (pp)
  355. X        fprintf(pp, "%-20.20s %s\n",
  356. X            opts->m_str, map_func_names[opts->m_cmd].m_str);
  357. X        else
  358. X        wprint("%-20.20s %s\n",
  359. X            opts->m_str, map_func_names[opts->m_cmd].m_str);
  360. X    else
  361. X        if (strcmp(str, opts->m_str))
  362. X        continue;
  363. X        else if (opts->m_cmd)
  364. X        return opts->m_cmd;
  365. X        else
  366. X        return 0;
  367. X    if (pp)
  368. X    (void) pclose(pp);
  369. X    if (incurses)
  370. X    iscurses = TRUE;
  371. X    echo_off();
  372. X    turnoff(glob_flags, IGN_SIGS);
  373. X    return 0;
  374. X}
  375. X
  376. X/*
  377. X * doesn't touch messages: return -1.  Error output causes return < -1.
  378. X */
  379. Xdo_bind(str, func)
  380. Xregister char *str;
  381. X{
  382. X    register struct cmd_map *list;
  383. X    register int match, ret = -1;
  384. X
  385. X    (void) un_bind(str);
  386. X    for (list = cmd_map; list; list = list->m_next)
  387. X    if ((match = prefix(str, list->m_str)) == MATCH)
  388. X        puts("Something impossible just happened."), ret--;
  389. X    else if (match == A_PREFIX_B)
  390. X        printf("Warning: \"%s\" prefixes \"%s\" (%s)\n",
  391. X        str, list->m_str, map_func_names[list->m_cmd].m_str), ret--;
  392. X    else if (match == B_PREFIX_A)
  393. X        printf("Warning: \"%s\" (%s) prefixes: \"%s\"\n",
  394. X        list->m_str, map_func_names[list->m_cmd].m_str, str), ret--;
  395. X    add_bind(str, func);
  396. X    /* errors decrement ret.  If ret returns less than -1, cntd_cmd is set
  397. X     * and no redrawing is done so user can see the warning signs
  398. X     */
  399. X    return ret;
  400. X}
  401. X
  402. Xadd_bind(str, func)
  403. Xregister char *str;
  404. X{
  405. X    register struct cmd_map *tmp;
  406. X    struct cmd_map *calloc();
  407. X
  408. X    /* now make a new option struct and set fields */
  409. X    if (!(tmp = calloc((unsigned)1, sizeof(struct cmd_map)))) {
  410. X    error("calloc");
  411. X    return;
  412. X    }
  413. X    tmp->m_next = cmd_map;
  414. X    cmd_map = tmp;
  415. X
  416. X    tmp->m_str = savestr(str);
  417. X    tmp->m_cmd = func; /* strdup handles the NULL case */
  418. X}
  419. X
  420. Xun_bind(p)
  421. Xregister char *p;
  422. X{
  423. X    register struct cmd_map *list = cmd_map, *tmp;
  424. X
  425. X    if (!list || !*list->m_str || !p || !*p)
  426. X    return 0;
  427. X
  428. X    if (!strcmp(p, cmd_map->m_str)) {
  429. X    cmd_map = cmd_map->m_next;
  430. X    xfree (list->m_str);
  431. X    xfree((char *)list);
  432. X    return 1;
  433. X    }
  434. X    for ( ; list->m_next; list = list->m_next)
  435. X    if (!strcmp(p, list->m_next->m_str)) {
  436. X        tmp = list->m_next;
  437. X        list->m_next = list->m_next->m_next;
  438. X        xfree (tmp->m_str);
  439. X        xfree ((char *)tmp);
  440. X        return 1;
  441. X    }
  442. X    return 0;
  443. X}
  444. X
  445. Xprefix(a, b)
  446. Xregister char *a, *b;
  447. X{
  448. X    while (*a && *b && *a == *b)
  449. X    a++, b++;
  450. X    if (!*a && !*b)
  451. X    return MATCH;
  452. X    if (!*a && *b)
  453. X    return A_PREFIX_B;
  454. X    if (*a && !*b)
  455. X    return B_PREFIX_A;
  456. X    return NO_MATCH;
  457. X}
  458. X#endif CURSES
  459. END_OF_FILE
  460. if test 11484 -ne `wc -c <'bind.c'`; then
  461.     echo shar: \"'bind.c'\" unpacked with wrong size!
  462. fi
  463. # end of 'bind.c'
  464. fi
  465. if test -f 'doproc.c' -a "${1}" != "-c" ; then 
  466.   echo shar: Will not clobber existing file \"'doproc.c'\"
  467. else
  468. echo shar: Extracting \"'doproc.c'\" \(12405 characters\)
  469. sed "s/^X//" >'doproc.c' <<'END_OF_FILE'
  470. X/* @(#)doproc.c        (c) copyright    10/18/86 (Dan Heller) */
  471. X
  472. X/* do main panel item procedures */
  473. X#include "mush.h"
  474. X
  475. Xrespond_mail(item, value, event)
  476. XPanel_item item;
  477. Xint value;
  478. Xstruct inputevent *event;
  479. X{
  480. X    char buf[80];
  481. X
  482. X    if (value == 4)
  483. X    return help(panel_sw->ts_windowfd, "respond", tool_help);
  484. X    if (ison(glob_flags, IS_GETTING)) {
  485. X    print("Finish editing current message first");
  486. X    return;
  487. X    }
  488. X    if (!msg_cnt) {
  489. X    print("No messages to respond to.\n");
  490. X    return;
  491. X    }
  492. X    print("Responding to message %d", current_msg+1);
  493. X    if (event && event->ie_code == MS_LEFT)
  494. X    value = 0;
  495. X    (void) sprintf(buf, "%s %s %d",
  496. X    (value == 2 || value == 3)? "replyall" : "replysender",
  497. X    (value == 1 || value == 3)? "-i": NO_STRING, current_msg+1);
  498. X    (void) cmd_line(buf, msg_list);
  499. X}
  500. X
  501. X/* following macro is for the next two procedures */
  502. X#define hdr_item (item == sub_hdr_item[0] || item == sub_hdr_item[1] || \
  503. X                  item == sub_hdr_item[2] || item == sub_hdr_item[3] || \
  504. X                  item == sub_hdr_item[4] || item == sub_hdr_item[5])
  505. X
  506. Xdelete_mail(item, val, event)
  507. Xregister Panel_item item;
  508. Xint val;
  509. Xregister struct inputevent *event;
  510. X{
  511. X    register int value = val, c;
  512. X    char buf[92];
  513. X
  514. X    panel_set(item, PANEL_VALUE, 0, 0);
  515. X    if (hdr_item && event->ie_code != MS_LEFT || value == 6)
  516. X    return help(panel_sw->ts_windowfd, "delete", tool_help);
  517. X    /* if selected "delete" in header panel, set value = 4 (delete "range") */
  518. X    if (hdr_item)
  519. X    value = 4;
  520. X    /* delete current message */
  521. X    if (!value || value == 1 && event && event->ie_code == MS_LEFT)
  522. X    if (ison(msg[current_msg].m_flags, DELETE)) {
  523. X        print("%d Already deleted", current_msg+1);
  524. X        return;
  525. X    } else {
  526. X        print("Deleted Message %d. ", current_msg+1);
  527. X        (void) strcpy(buf, "delete");
  528. X    }
  529. X    else switch(value) {
  530. X    case 1:
  531. X        print("Really delete everything?");
  532. X        if ((c = confirm(panel_sw->ts_windowfd)) == 'y' ||
  533. X             c == MS_LEFT) {
  534. X        print("Deleted All Messages. ");
  535. X        (void) strcpy(buf, "delete *");
  536. X        } else { print("Whew!"); return; }
  537. X    when 2:
  538. X        /* undelete current message */
  539. X        if (isoff(msg[current_msg].m_flags, DELETE)) {
  540. X        print("%d isn't deleted", current_msg+1);
  541. X        return;
  542. X        }
  543. X        print("Undeleted Message #%d. ", current_msg+1);
  544. X        (void) strcpy(buf, "undelete");
  545. X    when 3:
  546. X        /* undelete all messages */
  547. X        print("Uneleted All Messages. ");
  548. X        (void) strcpy (buf, "undelete *");
  549. X    when 4: case 5:
  550. X        /* delete a range of messages */
  551. X        (void) sprintf(buf, "%selete \"%s\"", (value == 4)? "d": "und",
  552. X            panel_get_value(msg_num_item));
  553. X        panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
  554. X    }
  555. X    (void) cmd_line(buf, msg_list);
  556. X}
  557. X
  558. Xread_mail(item, value, event)
  559. Xregister Panel_item item;
  560. Xregister int value;
  561. Xregister struct inputevent *event;
  562. X{
  563. X    register int this_msg = current_msg;
  564. X
  565. X    /* check "event" in case we were called from select.c
  566. X     * in which case event would be NULL
  567. X     */
  568. X    if (event && event->ie_code == MS_RIGHT &&
  569. X        item && (item == read_item && value ||
  570. X    (item == sub_hdr_item[0] || item == sub_hdr_item[1])))
  571. X    return help(panel_sw->ts_windowfd, "next", tool_help);
  572. X    if (item && (item == sub_hdr_item[4] || item == sub_hdr_item[5]))
  573. X    return help(panel_sw->ts_windowfd, "msg_menu", tool_help);
  574. X    if (!msg_cnt) {
  575. X    print ("No Mail.");
  576. X    return -1;
  577. X    }
  578. X    if (item && item == read_item || ison(msg[current_msg].m_flags, DELETE))
  579. X    (void) next_msg(FALSE, DELETE);
  580. X    if (this_msg != current_msg || ison(msg[current_msg].m_flags, UNREAD) ||
  581. X        (current_msg < n_array[0] || current_msg > n_array[screen])) {
  582. X    set_isread(current_msg);
  583. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  584. X    }
  585. X    display_msg(current_msg, (long)0);
  586. X    return -1;
  587. X}
  588. X
  589. X/* the panel button that says "filename" and "directory", etc... text item */
  590. Xfile_dir(item, event)
  591. XPanel_item item;
  592. Xstruct inputevent *event;
  593. X{
  594. X    register char *p;
  595. X    char buf[128], *which = panel_get(item, PANEL_LABEL_STRING);
  596. X
  597. X    if (!strcmp(which, "folder:"))
  598. X    if (event->ie_code == '\n' || event->ie_code == '\r')
  599. X        (void) sprintf(buf, "folder %s", panel_get_value(item));
  600. X    else
  601. X        (void) sprintf(buf, "folder ! %s", panel_get_value(item));
  602. X
  603. X    else if (!strcmp(which, "directory:"))
  604. X    (void) sprintf(buf, "cd %s", panel_get_value(item));
  605. X
  606. X    else if (!msg_cnt)
  607. X    print("No messages to save");
  608. X
  609. X    else if (!strcmp(which, "filename:")) {
  610. X    int x = 1;
  611. X    if (event->ie_code == '\n' || event->ie_code == '\r')
  612. X        (void) strcpy(buf, "save  ");
  613. X    else
  614. X        (void) strcpy(buf, "write ");
  615. X    if (!(p = panel_get_value(item)) || !*p &&
  616. X        (!(p = do_set(set_options, "mbox")) || !*p))
  617. X        p = DEF_MBOX;
  618. X    (void) sprintf(buf+6, "%d %s", current_msg+1, p);
  619. X    print("save message %d in %s? ", current_msg+1, p);
  620. X    if ((x = confirm(print_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
  621. X        print("Message not saved");
  622. X        return;
  623. X    }
  624. X    }
  625. X    (void) cmd_line(buf, msg_list);
  626. X}
  627. X
  628. Xdo_file_dir(item, value, event)
  629. XPanel_item item;
  630. Xint value;
  631. Xstruct inputevent *event;
  632. X{
  633. X    char buf[92];
  634. X    int x; /* used for confirmation */
  635. X
  636. X    if (item == folder_item) {
  637. X    (void) strcpy(buf, "folder ");
  638. X    if (event->ie_code == MS_LEFT) {
  639. X        panel_set(file_item, PANEL_LABEL_STRING, "folder:", 0);
  640. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  641. X                "Change without updating current folder", 0, 0);
  642. X    } else {
  643. X        if (!value)
  644. X        (void) strcat(buf, "%");
  645. X        else if (value == 1)
  646. X        (void) strcat(buf, "&");
  647. X        else if (value == 2)
  648. X        (void) strcat(buf, "#");
  649. X        else {
  650. X        (void) sprintf(buf, "folder %s",
  651. X                  panel_get(item, PANEL_CHOICE_STRING, value));
  652. X        if (!strcmp(buf+8, "Help"))
  653. X            return help(panel_sw->ts_windowfd, "folder", tool_help);
  654. X        }
  655. X    }
  656. X    } else if (item == cd_item) {
  657. X    (void) strcpy(buf, "cd ");
  658. X    if (event->ie_code == MS_LEFT || !value) {
  659. X        panel_set(file_item, PANEL_LABEL_STRING, "directory:", 0);
  660. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  661. X                "Change to specified directory", 0, 0);
  662. X    } else if (value == 1)
  663. X        (void) strcat(buf, "~");
  664. X    else if (value == 2)
  665. X        (void) strcat(buf, "+");
  666. X    else
  667. X        return help(panel_sw->ts_windowfd, "chdir", tool_help);
  668. X    } else if (item == save_item) {
  669. X    (void) strcpy(buf, "save ");
  670. X    if (event->ie_code == MS_LEFT)
  671. X        if (!strcmp("filename:", panel_get(file_item,PANEL_LABEL_STRING))) {
  672. X        event->ie_code = '\n';  /* let file_dir think it got a \n */
  673. X        return file_dir(file_item, event);
  674. X        } else {
  675. X        panel_set(file_item, PANEL_LABEL_STRING, "filename:", 0);
  676. X        panel_set(file_item, PANEL_MENU_CHOICE_STRINGS,
  677. X            "Save message WITHOUT headers", 0,0);
  678. X        print("Type in Main Panel Window a filename to save message");
  679. X        return;
  680. X        }
  681. X    else if (value == 1) {
  682. X        register char *p = panel_get_value(file_item);
  683. X        if ((!p || !*p) && (!(p = do_set(set_options, "mbox")) || !*p))
  684. X        p = DEF_MBOX;
  685. X        print("Save in %s? ", p);
  686. X        if ((x = confirm(panel_sw->ts_windowfd)) != 'y' && x != MS_LEFT) {
  687. X        print("Message not saved");
  688. X        return;
  689. X        }
  690. X        (void) sprintf(buf, "save \"%s\" %s",
  691. X                       panel_get_value(msg_num_item), p);
  692. X        panel_set(msg_num_item, PANEL_VALUE, NO_STRING, 0);
  693. X    } else {
  694. X        (void) sprintf(buf, "save %s",
  695. X        panel_get(item, PANEL_CHOICE_STRING, value));
  696. X        if (!strcmp(buf+6, "Help"))
  697. X        return help(panel_sw->ts_windowfd, "save", tool_help);
  698. X    }
  699. X    }
  700. X    (void) cmd_line(buf, msg_list);
  701. X    panel_set(item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
  702. X}
  703. X
  704. Xtext_done(item, event)
  705. XPanel_item item;
  706. Xstruct inputevent *event;
  707. X{
  708. X    char opt[30], buf[82], cmd[82];
  709. X    register char *p;
  710. X    Panel_item which = NO_ITEM;
  711. X    int set_it;
  712. X
  713. X    if ((event->ie_code == '\n' || event->ie_code == '\r') && 
  714. X                 *strcpy(buf, panel_get_value(item))) {
  715. X    (void) strcpy(opt, panel_get(item, PANEL_LABEL_STRING));
  716. X    set_it = (*opt == 'S');
  717. X    if (!(p = index(opt, ' '))) {
  718. X        print("Hmmm... there seems to be a problem here.");
  719. X        return;
  720. X    }
  721. X    ++p;
  722. X    switch(lower(*p)) {
  723. X        case 'o':
  724. X        (void) sprintf(cmd, "%set %s", (set_it)? "s": "uns", buf);
  725. X        which = option_item;
  726. X        when 'i':
  727. X        (void) sprintf(cmd, "%sgnore %s", (set_it)? "i": "uni", buf);
  728. X        which = ignore_item;
  729. X        when 'a':
  730. X        (void) sprintf(cmd, "%slias %s", (set_it)? "a": "una", buf);
  731. X        which = alias_item;
  732. X        otherwise: print("HUH!? (%c)", *p); return;
  733. X    }
  734. X    (void) cmd_line(buf, msg_list);
  735. X    }
  736. X    panel_set(input_item, PANEL_VALUE, NO_STRING, 0); /* remove last value */
  737. X    panel_set(item, PANEL_SHOW_ITEM, FALSE, 0);
  738. X}
  739. X
  740. Xdo_help(item, value, event)
  741. XPanel_item item;
  742. Xregister int value;
  743. Xstruct inputevent *event;
  744. X{
  745. X    register char *p, *helpfile = tool_help;
  746. X    switch(value) {
  747. X    case 1: p = "help";
  748. X    when 2: p = "mouse";
  749. X    when 3: p = "windows";
  750. X    when 4: p = "function keys";
  751. X    when 5: p = "hdr_format", helpfile = cmd_help;
  752. X    when 6: p = "msg_list", helpfile = cmd_help;
  753. X    otherwise: p = "general";
  754. X    }
  755. X    (void) help(panel_sw->ts_windowfd, p, helpfile);
  756. X}
  757. X
  758. Xtoolquit(item, value, event)
  759. XPanel_item item;
  760. Xint value;
  761. Xstruct inputevent *event;
  762. X{
  763. X    register int which;
  764. X
  765. X    if (!value || event->ie_code == MS_LEFT) {
  766. X    do_update(NO_ITEM, 0, NO_EVENT);
  767. X    turnoff(glob_flags, NEW_MAIL);
  768. X    mail_status(0); /* lower flag (if up) print current num of msgs */
  769. X    wmgr_changestate (tool->tl_windowfd, rootfd, TRUE);
  770. X    wmgr_changelevel (tool->tl_windowfd, parentfd, TRUE);
  771. X    return;
  772. X    } else if (value == 2) {
  773. X    (void) help(panel_sw->ts_windowfd, "quit", tool_help);
  774. X    return;
  775. X    }
  776. X    print("Left updates changes. Middle does not. Right aborts quit.");
  777. X    if ((which = confirm(panel_sw->ts_windowfd)) == MS_RIGHT) {
  778. X    print("Quit aborted.");
  779. X    return;
  780. X    }
  781. X    abort_mail(NO_ITEM, 0);
  782. X    if (which == MS_LEFT)
  783. X    lock_cursors(), copyback();
  784. X    else
  785. X    print("Bye bye");
  786. X    cleanup(0);
  787. X}
  788. X
  789. Xdo_lpr(item, value, event)
  790. XPanel_item item;
  791. Xint value;
  792. Xstruct inputevent *event;
  793. X{
  794. X    char buf[128];
  795. X
  796. X    if (event && (event->ie_code == MS_LEFT || value == 1)) {
  797. X    print("Sending message %d to printer...", current_msg+1);
  798. X    (void) strcpy(buf, "lpr ");
  799. X    if (value)
  800. X        (void) sprintf(buf, "lpr \"%s\"", panel_get_value(msg_num_item));
  801. X    lock_cursors();
  802. X    (void) cmd_line(buf, msg_list);
  803. X    unlock_cursors();
  804. X    } else
  805. X    (void) help(panel_sw->ts_windowfd, "printer", tool_help);
  806. X}
  807. X
  808. Xdo_clear()
  809. X{
  810. X    /* actions that clears window indicates user wants to quit getting opts */
  811. X    if (msg_pix)
  812. X    pr_destroy(msg_pix), msg_pix = (struct pixrect *)NULL;
  813. X    if (getting_opts)
  814. X    getting_opts = 0, unlock_cursors();
  815. X    pw_writebackground(msg_win, 0,0, msg_rect.r_width,msg_rect.r_height,
  816. X               PIX_CLR);
  817. X    txt.x = 5, txt.y = l_height(curfont) - 1;
  818. X}
  819. X
  820. Xdo_update(item, value, event)
  821. XPanel_item item;
  822. Xregister int value;
  823. Xstruct inputevent *event;
  824. X{
  825. X    char *argv[2];
  826. X    if (event && event->ie_code != MS_LEFT)
  827. X    return help(panel_sw->ts_windowfd, "update", tool_help);
  828. X    argv[0] = "update";
  829. X    argv[1] = NULL;
  830. X    (void) folder(0, argv, NULL);
  831. X}
  832. X
  833. X/* panel selction button to send a letter.
  834. X * add a CR if necessary, and finish up letter
  835. X */
  836. Xdo_send(item, value, event)
  837. XPanel_item item;
  838. Xregister int value;
  839. Xregister struct inputevent *event;
  840. X{
  841. X    if (event->ie_code != MS_LEFT)
  842. X    return help(panel_sw->ts_windowfd, "send", tool_help);
  843. X    if (txt.x > 5) {
  844. X    pw_char(msg_win, txt.x,txt.y, PIX_CLR, fonts[curfont], '_');
  845. X    add_to_letter(rite('\n')); /* if line isn't complete, flush it */
  846. X    }
  847. X    finish_up_letter();
  848. X}
  849. X
  850. Xdo_edit(item, value, event)
  851. XPanel_item item;
  852. Xregister int value;
  853. Xregister struct inputevent *event;
  854. X{
  855. X    char buf[4];
  856. X    if (event->ie_code != MS_LEFT)
  857. X    return help(panel_sw->ts_windowfd, "edit", tool_help);
  858. X    if (txt.x > 5)
  859. X    add_to_letter(rite('\n')); /* flush line for him */
  860. X    add_to_letter(sprintf(buf, "%cv", *escape));
  861. X}
  862. X
  863. Xdo_compose(item, value, event)
  864. XPanel_item item;
  865. Xregister int value;
  866. Xstruct inputevent *event;
  867. X{
  868. X    if (event && event->ie_code != MS_LEFT)
  869. X    return help(panel_sw->ts_windowfd, "compose", tool_help);
  870. X    print("Composing letter.");
  871. X    win_setcursor(msg_sw->ts_windowfd, &write_cursor);
  872. X    do_mail(0, DUBL_NULL, NULL);
  873. X}
  874. X
  875. Xchange_font(item, value, event)
  876. XPanel_item item;
  877. Xregister int value;
  878. Xstruct inputevent event;
  879. X{
  880. X    if (ison(glob_flags, IS_GETTING))
  881. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC^PIX_DST, fonts[curfont], '_');
  882. X    curfont = value % total_fonts;
  883. X    print("New font: %s\n",
  884. X        (!curfont)? "Normal": (curfont == 1)? "Small": "Large");
  885. X    if (ison(glob_flags, IS_GETTING))
  886. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC^PIX_DST, fonts[curfont], '_');
  887. X    crt = msg_rect.r_height / l_height(curfont);
  888. X}
  889. END_OF_FILE
  890. if test 12405 -ne `wc -c <'doproc.c'`; then
  891.     echo shar: \"'doproc.c'\" unpacked with wrong size!
  892. fi
  893. # end of 'doproc.c'
  894. fi
  895. if test -f 'init.c' -a "${1}" != "-c" ; then 
  896.   echo shar: Will not clobber existing file \"'init.c'\"
  897. else
  898. echo shar: Extracting \"'init.c'\" \(10998 characters\)
  899. sed "s/^X//" >'init.c' <<'END_OF_FILE'
  900. X/* init.c    (c) copyright 1986 (Dan Heller) */
  901. X
  902. X/* init.c -- functions and whatnot that initialize everything */
  903. X#include "mush.h"
  904. X#include <pwd.h>
  905. X
  906. X#ifdef SUNTOOL
  907. X/* mouse symbols */
  908. Xshort dat_mouse_left[] = {
  909. X#include <images/confirm_left.pr> 
  910. X};
  911. X
  912. Xshort dat_mouse_middle[] = {
  913. X#include <images/confirm_middle.pr> 
  914. X};
  915. X
  916. Xshort dat_mouse_right[] = {
  917. X#include <images/confirm_right.pr> 
  918. X};
  919. X
  920. Xshort dat_mail_icon_1[] = {
  921. X#include "mail.icon.1"
  922. X};
  923. X
  924. Xshort dat_mail_icon_2[] = {
  925. X#include "mail.icon.2"
  926. X};
  927. X
  928. Xshort dat_coffee_cup[] = {
  929. X#include "coffee.cup.pr"
  930. X};
  931. X
  932. Xshort dat_read_cursor[] = {
  933. X#include "glasses.pr"
  934. X};
  935. X
  936. Xshort dat_write_cursor[] = {
  937. X#include "write.pr"
  938. X};
  939. X
  940. Xshort dat_up_arrow[] = {
  941. X#include "up.arrow.pr"
  942. X};
  943. X
  944. Xshort dat_dn_arrow[] = {
  945. X#include "dn.arrow.pr"
  946. X};
  947. X
  948. Xshort dat_envelope[] = {
  949. X#include "envelope.pr"
  950. X};
  951. X
  952. Xshort dat_cycle_cursor[] = {
  953. X#include "cycle.pr"
  954. X};
  955. X
  956. Xshort dat_check_cursor[] = {
  957. X#include "check.pr"
  958. X};
  959. X
  960. Xmpr_static(mail_icon_image1, 64, 64, 1, dat_mail_icon_1);
  961. Xmpr_static(mail_icon_image2, 64, 64, 1, dat_mail_icon_2);
  962. X
  963. Xmpr_static(mouse_left,      16, 16, 1, dat_mouse_left);
  964. Xmpr_static(mouse_middle,    16, 16, 1, dat_mouse_middle);
  965. Xmpr_static(mouse_right,     16, 16, 1, dat_mouse_right);
  966. Xmpr_static(coffee_cup,      16, 16, 1, dat_coffee_cup);
  967. Xmpr_static(glasses_cursor,  16, 16, 1, dat_read_cursor);
  968. Xmpr_static(pencil_cursor,   16, 16, 1, dat_write_cursor);
  969. Xmpr_static(up_arrow,        16, 16, 1, dat_up_arrow);
  970. Xmpr_static(dn_arrow,        16, 16, 1, dat_dn_arrow);
  971. Xmpr_static(envelope_cursor, 16, 16, 1, dat_envelope);
  972. Xmpr_static(cycle,           16, 16, 1, dat_cycle_cursor);
  973. Xmpr_static(check_cursor,    16, 16, 1, dat_check_cursor);
  974. X
  975. Xstruct cursor l_cursor     = { 3, 3, PIX_SRC,         &mouse_left      };
  976. Xstruct cursor m_cursor     = { 3, 3, PIX_SRC,         &mouse_middle    };
  977. Xstruct cursor r_cursor     = { 3, 3, PIX_SRC,         &mouse_right     };
  978. Xstruct cursor coffee       = { 8, 8, PIX_SRC,         &coffee_cup      };
  979. Xstruct cursor read_cursor  = { 8, 8, PIX_SRC|PIX_DST, &glasses_cursor  };
  980. Xstruct cursor write_cursor = { 8, 8, PIX_SRC|PIX_DST, &pencil_cursor   };
  981. Xstruct cursor main_cursor  = { 8, 8, PIX_SRC,         &envelope_cursor };
  982. Xstruct cursor checkmark = { 8, 8, PIX_SRC|PIX_DST, &check_cursor };
  983. X
  984. X/* text and font will be set in mail_status() */
  985. Xstruct icon mail_icon = { 64,  64, (struct pixrect *)NULL,
  986. X            { 0, 0, 64, 64 }, &mail_icon_image1,
  987. X            { 5, 5, 26, 12 }, NULL, (struct pixfont *)NULL, 0 };
  988. X
  989. Xchar *font_files[] = {
  990. X    "serif.r.14", "sail.r.6", "serif.r.16",
  991. X};
  992. X
  993. Xchar *alt_fonts[] = {
  994. X    "gacha.r.8", "sail.r.6", "screen.r.14",
  995. X};
  996. X
  997. X#endif SUNTOOL
  998. X
  999. X#ifdef BSD
  1000. X#include <netdb.h>
  1001. X#endif BSD
  1002. X
  1003. Xvoid
  1004. Xinit()
  1005. X{
  1006. X    char         buf[BUFSIZ], cwd[128], *home;
  1007. X    extern char        *getwd(), *getlogin();
  1008. X#ifdef SYSV
  1009. X    char *getcwd();
  1010. X    extern struct passwd *getpwuid();  /* sys-v forgot this in pwd.h! */
  1011. X#else
  1012. X    char ourhost[128];
  1013. X#endif SYSV
  1014. X    register char     *p, *p2 = buf, **argv;
  1015. X    struct passwd     *entry;
  1016. X    int            cnt = 0;
  1017. X#ifdef BSD
  1018. X    struct hostent     *hp;
  1019. X#endif BSD
  1020. X
  1021. X    home = getenv ("HOME");
  1022. X
  1023. X    if (!(entry = getpwuid(getuid())))
  1024. X    if (p = getlogin())
  1025. X        strdup(login, p);
  1026. X    else {
  1027. X        login = "unknown";
  1028. X        print("I don't know you, but that's ok.\n");
  1029. X    }
  1030. X    else {
  1031. X    strdup(login, entry->pw_name);
  1032. X    if (!home || !*home)
  1033. X        home = entry->pw_dir;
  1034. X    endpwent();
  1035. X    }
  1036. X    if (!home || !*home || access(home, 2)) {
  1037. X    error(home);
  1038. X    home = ALTERNATE_HOME;
  1039. X    print_more("Using \"%s\" as home.\n", home);
  1040. X    }
  1041. X
  1042. X#ifndef SYSV
  1043. X    (void) gethostname(ourhost, sizeof ourhost);
  1044. X    if (!(hp = gethostbyname(ourhost)))
  1045. X    error("gethostbyname: %s", ourhost);
  1046. X    else for (p = hp->h_name; p && *p && cnt < MAX_HOST_NAMES;
  1047. X          p = hp->h_aliases[cnt++])
  1048. X    ourname[cnt] = savestr(p);
  1049. X    endhostent();
  1050. X#endif SYSV
  1051. X
  1052. X#ifndef SYSV
  1053. X    if (getwd(cwd) == NULL)
  1054. X#else
  1055. X    if (getcwd(cwd, 128) == NULL)
  1056. X#endif SYSV
  1057. X    error("getcwd: %s", cwd), *cwd = 0;
  1058. X
  1059. X    p2 += strlen(strcpy(p2, "set "));
  1060. X    p2 += strlen(sprintf(p2, "cwd=\"%s\" ", cwd));
  1061. X    p2 += strlen(sprintf(p2, "home=\"%s\" ", home));
  1062. X    p2 += strlen(sprintf(p2, "prompt=\"%s\" ", DEF_PROMPT));
  1063. X    p2 += strlen(sprintf(p2, "mbox=\"%s\" ",   DEF_MBOX));
  1064. X    p2 += strlen(sprintf(p2, "folder=\"%s\" ", DEF_FOLDER));
  1065. X    p2 += strlen(sprintf(p2, "escape=\"%s\" ", DEF_ESCAPE));
  1066. X
  1067. X    p = getenv("SHELL");
  1068. X    p2 += strlen(sprintf(p2, "shell=\"%s\" ", (p)? p: DEF_SHELL));
  1069. X
  1070. X    p = getenv("EDITOR");
  1071. X    p2 += strlen(sprintf(p2, "editor=\"%s\" ", (p)? p: DEF_EDITOR));
  1072. X
  1073. X    p = getenv("VISUAL");
  1074. X    p2 += strlen(sprintf(p2, "visual=\"%s\" ", (p)? p: DEF_EDITOR));
  1075. X
  1076. X    p = getenv("PAGER");
  1077. X    p2 += strlen(sprintf(p2, "pager=\"%s\" ", (p)? p: DEF_PAGER));
  1078. X
  1079. X    p = getenv("PRINTER");
  1080. X    p2 += strlen(sprintf(p2, "printer=\"%s\" ", (p)? p: DEF_PRINTER));
  1081. X
  1082. X    crt = 25;
  1083. X    /* p2 += strlen(strcat(p2, "crt=\"25\" ")); */
  1084. X    screen = 18;
  1085. X    /* p2 += strlen(strcat(p2, "screen=\"18\" ")); */
  1086. X
  1087. X    if (!(argv = make_command(buf, TRPL_NULL, &cnt)))
  1088. X    print("error initializing variables.\n");
  1089. X    else {
  1090. X    (void) set(cnt, argv);
  1091. X    free_vec(argv);
  1092. X    }
  1093. X#ifdef CURSES
  1094. X    init_bindings();
  1095. X#endif CURSES
  1096. X}
  1097. X
  1098. X/*
  1099. X * Source a file, or just the default file.  Since sourcing files
  1100. X * means reading possible aliases, don't expand the ! as history
  1101. X * by setting the IGN_BANG flag.  Since a command in the sourced file
  1102. X * may call source on another file, this routine may be called from
  1103. X * within itself.  Continue to ignore ! chars by setting save_bang (local).
  1104. X *
  1105. X * Try opening the file passed to us.  If not given, check for the correct
  1106. X * .rc file which is found in the user's home dir.
  1107. X */
  1108. Xsource(argc, argv)
  1109. Xchar **argv;
  1110. X{
  1111. X    register char *p, *p2, **newargv;
  1112. X    int       line_no = 0, if_else = 0, parsing = 1, cont_line = 0;
  1113. X    FILE      *fp;
  1114. X    char       file[128], line[BUFSIZ];
  1115. X    long      save_bang = ison(glob_flags, IGN_BANG);
  1116. X
  1117. X    if (argc && *++argv && !strcmp(*argv, "-?"))
  1118. X    return help(0, "source_help", cmd_help);
  1119. X    if (argc && *argv)
  1120. X    (void) strcpy(file, *argv);
  1121. X    else if (p = getenv("MAILRC"))
  1122. X    (void) strcpy(file, p);
  1123. X    else {
  1124. X    char *home = do_set(set_options, "home");
  1125. X    if (!home || !*home)
  1126. X        home = ALTERNATE_HOME;
  1127. X    if (access(sprintf(file, "%s/%s", home, MAILRC), R_OK)
  1128. X          && access(sprintf(file, "%s/%s", home, ALTERNATE_RC), R_OK))
  1129. X    (void) strcpy(file, DEFAULT_RC);
  1130. X    }
  1131. X
  1132. X    argc = 0; /* don't ignore ENOENT */
  1133. X    p = getpath(file, &argc);
  1134. X    if (argc) {
  1135. X    if (strcmp(file, DEFAULT_RC))
  1136. X        if (argc == -1)
  1137. X        print("%s: %s\n", file, p);
  1138. X        else
  1139. X        print("%s is a directory.\n", file);
  1140. X    return -1;
  1141. X    }
  1142. X    if (!(fp = fopen(p, "r"))) {
  1143. X    if (errno != ENOENT)
  1144. X        error("Can't open %s", p);
  1145. X    return -1;
  1146. X    }
  1147. X    (void) strcpy(file, p);
  1148. X    turnon(glob_flags, IGN_BANG); /* ignore ! when reading record files */
  1149. X    while (p = fgets(&line[cont_line], BUFSIZ - cont_line, fp)) {
  1150. X    line_no++;
  1151. X    if (*(p2 = no_newln(line + cont_line)) == '\\') {
  1152. X        cont_line = p2 - line;
  1153. X        continue;
  1154. X    } else
  1155. X        cont_line = 0;
  1156. X    /* don't consider comments (#) in lines. check if # is within quotes */
  1157. X        if (p = any(p, "\"'#")) {
  1158. X        register int balanced = 1;
  1159. X        while (p && (*p == '\'' || *p == '"') && balanced) {
  1160. X        /* first find matching quote */
  1161. X        register char *quote = index(p+1, *p);
  1162. X        if (!quote) {
  1163. X            print("%s: line %d: unbalanced %c.\n", file, line_no, *p);
  1164. X            balanced = 0;
  1165. X        } else
  1166. X            p = any(quote+1, "'\"#");
  1167. X        }
  1168. X        if (!balanced)
  1169. X        continue;
  1170. X        if (p && *p == '#')
  1171. X        *p = 0; /* found a Comment: null terminate line at comment */
  1172. X    }
  1173. X    if (!*line || !(newargv = make_command(line, TRPL_NULL, &argc))) {
  1174. X        if (!strncmp(line, "if", 2))
  1175. X        if_else++, parsing = FALSE;
  1176. X        continue;
  1177. X    }
  1178. X    if (!strcmp(newargv[0], "endif")) {
  1179. X        if (!if_else)
  1180. X        print("%s: line %d: endif with no \"if\".\n", file, line_no);
  1181. X        else
  1182. X        if_else = 0, parsing = 1;
  1183. X        goto bad;
  1184. X    } else if (!strcmp(newargv[0], "else")) {
  1185. X        if (!if_else)
  1186. X        print("%s: line %d: if-less \"else\".\n", file, line_no);
  1187. X        else
  1188. X        parsing = !parsing;
  1189. X        goto bad;
  1190. X    } else if (parsing && !strcmp(newargv[0], "if")) {
  1191. X        /* if statements are of the form:
  1192. X         *     if expr
  1193. X         *     if !expr  or  if ! expr
  1194. X         *     if expr == expr   or   if expr != expr
  1195. X         */
  1196. X        int equals = TRUE;
  1197. X        register char *lhs = newargv[1], *rhs = NULL;
  1198. X
  1199. X        if (if_else)
  1200. X        print("%s: line %d: no nested if statements!\n", file, line_no);
  1201. X        else
  1202. X        if_else = 1;
  1203. X        parsing = 0;
  1204. X        if (!lhs || !*lhs) {
  1205. X        print("%s: line %d: if what?\n", file, line_no);
  1206. X        goto bad;
  1207. X        }
  1208. X        /* "lhs" is the left hand side of the equation
  1209. X         * In this instance, we're doing case 2 above.
  1210. X         */
  1211. X        if (*lhs == '!') {
  1212. X        int tmp = argc;
  1213. X        equals = FALSE;
  1214. X        if (!*++lhs)
  1215. X            if (!(lhs = newargv[2])) {
  1216. X            print("%s: %d: syntax error: \"if ! <what?>\"\n",
  1217. X                file, line_no);
  1218. X            goto bad;
  1219. X            } else
  1220. X            tmp--;
  1221. X        if (tmp > 2) {
  1222. X            print("%s: %d: syntax error: \"if !<expr> <more junk>\"\n",
  1223. X            file, line_no);
  1224. X            goto bad;
  1225. X        }
  1226. X        } else if (argc > 2) {
  1227. X        if (argc != 4) {
  1228. X            print("%s: %d: argument count error: line has %d args.\n",
  1229. X            file, line_no, argc);
  1230. X            goto bad;
  1231. X        }
  1232. X        /* now check newargv[1] for == or != */
  1233. X        if (!strcmp(newargv[2], "!="))
  1234. X            equals = FALSE;
  1235. X        else if (strcmp(newargv[2], "==")) {
  1236. X            print("%s: %d: use `==' or `!=' only.\n", file, line_no);
  1237. X            goto bad;
  1238. X        }
  1239. X        rhs = newargv[3];
  1240. X        }
  1241. X        if (!strcmp(lhs, "redirect") &&
  1242. X              (ison(glob_flags, REDIRECT) && equals ||
  1243. X               isoff(glob_flags, REDIRECT) && !equals)
  1244. X        || !strcmp(lhs, "istool") &&
  1245. X              (istool && equals || !istool && !equals)
  1246. X        || !strcmp(lhs, "hdrs_only") &&
  1247. X              (hdrs_only && equals || !hdrs_only && !equals)
  1248. X        || !strcmp(lhs, "iscurses") &&
  1249. X              ((iscurses || ison(glob_flags, PRE_CURSES)) && equals ||
  1250. X              (isoff(glob_flags, PRE_CURSES) && !iscurses && !equals)))
  1251. X            parsing = 1;
  1252. X        else if (rhs)
  1253. X        if (strcmp(lhs, rhs) && !equals || !strcmp(lhs, rhs) && equals)
  1254. X            parsing = 1;
  1255. Xbad:
  1256. X        free_vec(newargv);
  1257. X        continue;
  1258. X    }
  1259. X    if (parsing && argc > 0)
  1260. X        if (!strcmp(newargv[0], "exit")) {
  1261. X        if_else = 0;
  1262. X        break;
  1263. X        } else
  1264. X        (void) do_command(argc, newargv, msg_list);
  1265. X    else
  1266. X        free_vec(newargv);
  1267. X    }
  1268. X    if (if_else)
  1269. X    print("%s: missing endif\n", file);
  1270. X    fclose(fp);
  1271. X    /* if we entered the routine ignoring !, leave it that way. */
  1272. X    if (!save_bang)
  1273. X    turnoff(glob_flags, IGN_BANG);
  1274. X    return -1;
  1275. X}
  1276. X
  1277. X#ifdef SUNTOOL
  1278. X/* open all fonts and place in fonts array. */
  1279. Xgetfonts()
  1280. X{
  1281. X    char tmp[80];
  1282. X    register int offset = strlen(FONTDIR) + 1;
  1283. X    struct pixfont *pf_open();
  1284. X
  1285. X    (void) sprintf(tmp, "%s/", FONTDIR);
  1286. X    for (total_fonts = 0; total_fonts < MAX_FONTS; total_fonts++) {
  1287. X    (void) strcpy(&tmp[offset], font_files[total_fonts]);
  1288. X    if (!(fonts[total_fonts] = pf_open(tmp))) {
  1289. X        (void) strcpy(&tmp[offset], alt_fonts[total_fonts]);
  1290. X        if (!(fonts[total_fonts] = pf_open(tmp))) {
  1291. X        print("couldn't open font \"%s\"\n", tmp);
  1292. X        fonts[total_fonts] = pf_default();
  1293. X        }
  1294. X    }
  1295. X    }
  1296. X}
  1297. X#endif SUNTOOL
  1298. END_OF_FILE
  1299. if test 10998 -ne `wc -c <'init.c'`; then
  1300.     echo shar: \"'init.c'\" unpacked with wrong size!
  1301. fi
  1302. # end of 'init.c'
  1303. fi
  1304. if test -f 'viewopts.c' -a "${1}" != "-c" ; then 
  1305.   echo shar: Will not clobber existing file \"'viewopts.c'\"
  1306. else
  1307. echo shar: Extracting \"'viewopts.c'\" \(12717 characters\)
  1308. sed "s/^X//" >'viewopts.c' <<'END_OF_FILE'
  1309. X/* @(#)viewopts.c    (c) copyright    10/18/86 (Dan Heller) */
  1310. X
  1311. X#include "mush.h"
  1312. X
  1313. Xstruct viewopts {
  1314. X    char *v_opt;
  1315. X    char *v_prompt;
  1316. X    int  v_usage;
  1317. X#define TOOL  01
  1318. X#define TEXT  02
  1319. X    char *v_description;
  1320. X};
  1321. X
  1322. X/*
  1323. X * struct contains the option, a prompt if it has a string value, whether
  1324. X * or not it applies to non suntools, line mode, or both, and a
  1325. X * string describing what the option does. If the prompt string starts
  1326. X * with a minus sign, then the value can be set without a value. This
  1327. X * is there to indicate to option_line to print a toggle (cycle) pixrect
  1328. X * and to print TRUE/FALSE telling whether the value is on or off regardless
  1329. X * of it's "string" value.
  1330. X */
  1331. Xstruct viewopts viewopts[] = {
  1332. X    { "alwaysignore", NULL, TOOL | TEXT,
  1333. X      "alwaysignore the message headers on the 'ignored' list." },
  1334. X    { "askcc", NULL, TOOL | TEXT,
  1335. X      "Ask for list of Carbon Copy recipients whenever sending mail.", },
  1336. X    { "autodelete", NULL, TOOL | TEXT,
  1337. X      "Automatically delete ALL READ messages whenever you update mail.", },
  1338. X    { "autoedit", NULL, TOOL | TEXT,
  1339. X      "Automatically enter editor whenever you REPLY to mail.", },
  1340. X    { "autoinclude", NULL, TOOL | TEXT,
  1341. X      "Include a copy of author's message each time you reply to mail." },
  1342. X    { "autoprint", NULL, TOOL | TEXT,
  1343. X      "Display the next message on the list when you delete a message." },
  1344. X    { "auto_route", NULL, TOOL | TEXT,
  1345. X      "Automatic optimization of uucp paths is done removing redundancies." },
  1346. X    { "autosign", "-Filename", TOOL | TEXT,
  1347. X      "Add file (~/.signature if set but no value) at end of all letters." },
  1348. X    { "crt", "Lines", TEXT,
  1349. X      "The number of lines a message must have for 'pager' to be invoked." },
  1350. X    { "dead", "Filename", TOOL | TEXT,
  1351. X      "The name of the file to store dead mail. ~/dead.letter by default." },
  1352. X    { "dot", NULL, TOOL | TEXT,
  1353. X      "allow \".\" on a line by itself to send letter." },
  1354. X    { "editor", "Editor name/path", TOOL | TEXT,
  1355. X      "editor to use by default. Default is evironment EDITOR or \"vi\"" },
  1356. X    { "escape", "Character", TOOL | TEXT,
  1357. X      "Escape character for extended editing commands. (default = ~)" },
  1358. X    { "fixaddr", NULL, TOOL | TEXT,
  1359. X      "makes \"replyall\" route recipient addresses through sender's host." },
  1360. X    { "folder", "Pathname", TOOL | TEXT,
  1361. X      "Full pathname to the directory where personal folders are kept." },
  1362. X    { "fortune", "-Flag", TOOL | TEXT,
  1363. X      "Add fortune to end of letters. Flag to \"fortune\" is optional" },
  1364. X    { "fortunates", "Users", TOOL | TEXT,
  1365. X      "Those who will receive fortunes if fortune is set (default: All)." },
  1366. X    { "hdr_format", "Format", TOOL | TEXT,
  1367. X      "Formatting string for headers. \"headers -?\" or help hdr_format" },
  1368. X    { "history", "Number", TEXT,
  1369. X      "How many commands to remember (like csh)." },
  1370. X    { "hold", NULL, TOOL | TEXT,
  1371. X      "Read but not deleted messages are saved in spool -- not mbox." },
  1372. X    { "ignore_bang", NULL, TEXT,
  1373. X      "Ignore '!' as a history reference. Otherwise, escape by: \\!" },
  1374. X    { "ignoreeof", "-Command", TEXT,
  1375. X      "Ignores ^D as exit, or (if set), execute \"command\"." },
  1376. X    { "indent_str", "String", TOOL | TEXT,
  1377. X      "String to offset included messages within your letter", },
  1378. X    { "in_reply_to", NULL, TOOL | TEXT,
  1379. X      "When responding to mail, add In-Reply-To: to message headers." },
  1380. X    { "keepsave", NULL, TOOL | TEXT,
  1381. X      "Prevents messages from being marked as `deleted' when you `save'." },
  1382. X    { "known_hosts", "Host list", TOOL | TEXT,
  1383. X      "List of hosts that your site is known to uucp mail to." },
  1384. X    { "lister", "Arguemnts", TOOL | TEXT,
  1385. X      "Arguments passed to the 'ls' command." },
  1386. X    { "mbox", "Filename", TOOL | TEXT,
  1387. X      "Filename to use instead of ~/mbox for default mailbox." },
  1388. X    { "metoo", NULL, TOOL | TEXT,
  1389. X      "When replying to mail, metoo preserves your name on mailing list." },
  1390. X    { "newline", "-Command", TEXT,
  1391. X      "Ignore RETURN. If set to a string, execute \"command\"" },
  1392. X    { "no_hdr", NULL, TOOL | TEXT,
  1393. X      "If set, personalized headers are NOT inserted to outgoing mail." },
  1394. X    { "no_reverse", NULL, TOOL | TEXT,
  1395. X      "disables reverse video in curses mode -- uses \"bold\" in tool mode." },
  1396. X    { "nosave", NULL, TOOL | TEXT,
  1397. X      "prevents aborted mail from being saved in dead.letter" },
  1398. X    { "pager", "Program", TEXT,
  1399. X      "Program name to be used as a pager for messages longer than crt." },
  1400. X    { "print_cmd", "Program", TOOL | TEXT,
  1401. X      "Alternate program to use to send messages to the printer." },
  1402. X    { "printer", "Printer", TOOL | TEXT,
  1403. X      "Printer to send messages to. Default is environment PRINTER" },
  1404. X    { "prompt", "String", TEXT,
  1405. X      "Your prompt.  \"help prompt\" for more information." },
  1406. X    { "quiet", NULL, TEXT,
  1407. X      "Don't print the version number of Mush on startup." },
  1408. X    { "record", "Filename", TOOL | TEXT,
  1409. X      "Save all outgoing mail in specified filename" },
  1410. X    { "reply_to_hdr", "Headers", TOOL | TEXT,
  1411. X      "List of headers to search in messages to construct reply adresses.", },
  1412. X    { "screen", "Number of Headers", TEXT,
  1413. X      "Number of headers to print in non-suntools (text) mode" },
  1414. X    { "screen_win", "Number of Headers", TOOL,
  1415. X      "Set the size of the header window." },
  1416. X    { "show_deleted", NULL, TOOL | TEXT,
  1417. X      "Show deleted messages in headers listings" },
  1418. X    { "sort", "-Option", TOOL | TEXT,
  1419. X      "Sorting upon startup of mail or `update/folder' (sort -? for help)" },
  1420. X    { "squeeze", NULL, TOOL | TEXT,
  1421. X      "When reading messages, squeeze all blank lines into one." },
  1422. X    { "top", "Lines", TOOL | TEXT,
  1423. X      "Number of lines to print of a message for the 'top' command."  },
  1424. X    { "unix", NULL, TEXT,
  1425. X      "Non-mush commands are considered to be UNIX commands." },
  1426. X    { "verify", NULL, TEXT,
  1427. X      "Verify to send, re-edit, or abort letter after editing." },
  1428. X    { "visual", "Visual editor", TOOL | TEXT,
  1429. X      "Visual editor to use by default. \"editor\" is used if not set." },
  1430. X    { "warning", NULL, TOOL | TEXT,
  1431. X      "Warns when standard variables are set differently from the default." }
  1432. X};
  1433. X
  1434. Xstatic int total_opts;
  1435. X
  1436. X#ifdef NOT_NOW
  1437. X/*
  1438. X * put all the tool stuff at the beginning, or all the text stuff at
  1439. X * the beginning depending on whether or not we're running as a tool
  1440. X * With all the inappropriate variables out of the way, we set total
  1441. X * opts to the number of variables which are of the right type and
  1442. X * nothing inappropriate will ever be displayed.
  1443. X *
  1444. X * Note, this doesn't really work right now and I don't wanna fix it now..
  1445. X */
  1446. Xstatic
  1447. Xopt_eliminator(a, b)
  1448. Xregister struct viewopts *a, *b;
  1449. X{
  1450. X    if (istool)
  1451. X    return a->v_usage == TOOL;
  1452. X    return a->v_usage == TEXT;
  1453. X}
  1454. X#endif NOT_NOW
  1455. X
  1456. Xstatic
  1457. Xopt_sorter(a, b)
  1458. Xregister struct viewopts *a, *b;
  1459. X{
  1460. X    return !strcmp(a->v_opt, b->v_opt);
  1461. X}
  1462. X
  1463. Xsort_variables()
  1464. X{
  1465. X    /*
  1466. X    register int optnum;
  1467. X
  1468. X    for (optnum=0; optnum < sizeof viewopts / sizeof(struct viewopts); optnum++)
  1469. X    if (istool && viewopts[optnum].v_usage & TOOL
  1470. X        || !istool && viewopts[optnum].v_usage & TEXT)
  1471. X        total_opts++;
  1472. X    */
  1473. X    total_opts = sizeof viewopts / sizeof (struct viewopts);
  1474. X    qsort((char *)viewopts, sizeof viewopts / sizeof (struct viewopts),
  1475. X            sizeof(struct viewopts), opt_sorter);
  1476. X}
  1477. X
  1478. X#ifdef SUNTOOL
  1479. X
  1480. Xstatic int start_cnt;
  1481. X
  1482. X#define twenty     5 + 20*l_width(DEFAULT)
  1483. X#define forty     5 + 40*l_width(DEFAULT)
  1484. X#define image_at(x,y,image) pw_rop(msg_win, x, y, 16, 16, PIX_SRC, image, 0,0)
  1485. X
  1486. X/* print in default text, but increment in large text segments */
  1487. Xview_options()
  1488. X{
  1489. X    if (msg_rect.r_height < 80) {
  1490. X    print("Window not big enough to display options.");
  1491. X    return;
  1492. X    }
  1493. X    do_clear();
  1494. X    getting_opts = 1, start_cnt = 0;
  1495. X    win_setcursor(msg_sw->ts_windowfd, &checkmark);
  1496. X    highlight(msg_win, txt.x, txt.y, LARGE,
  1497. X        "    : Toggle Value       : Description       : Menu (Help)");
  1498. X    image_at(txt.x +  2 * l_width(DEFAULT), txt.y - 12, &mouse_left);
  1499. X    image_at(txt.x + 25 * l_width(DEFAULT), txt.y - 12, &mouse_middle);
  1500. X    image_at(txt.x + 48 * l_width(DEFAULT), txt.y - 12, &mouse_right);
  1501. X
  1502. X    pw_vector(msg_win, 0, txt.y+6, msg_rect.r_width, txt.y+6, PIX_SRC, 1);
  1503. X    pw_vector(msg_win, 0, txt.y+8, msg_rect.r_width, txt.y+8, PIX_SRC, 1);
  1504. X
  1505. X    txt.y += 24;
  1506. X
  1507. X    pw_text(msg_win, 5,      txt.y, PIX_SRC, fonts[LARGE], "Option");
  1508. X    pw_text(msg_win, twenty, txt.y, PIX_SRC, fonts[LARGE], "On/Off");
  1509. X    pw_text(msg_win, forty,  txt.y, PIX_SRC, fonts[LARGE], "Values");
  1510. X
  1511. X    pw_vector(msg_win, 0, txt.y+6, msg_rect.r_width, txt.y+6, PIX_SRC, 1);
  1512. X    pw_vector(msg_win, 0, txt.y+8, msg_rect.r_width, txt.y+8, PIX_SRC, 1);
  1513. X
  1514. X    pw_text(msg_win, 59*l_width(DEFAULT),txt.y,PIX_SRC,fonts[LARGE],"Scroll:");
  1515. X    pw_rop(msg_win, 60*l_width(LARGE), txt.y-13,16,16,PIX_SRC, &dn_arrow,0,0);
  1516. X    pw_rop(msg_win, 60*l_width(LARGE)+20,txt.y-13,16,16,PIX_SRC, &up_arrow,0,0);
  1517. X
  1518. X    display_opts(0); /* create the pixrect and all that */
  1519. X}
  1520. X
  1521. Xdisplay_opts(count)
  1522. Xregister int count;
  1523. X{
  1524. X    register int total_displayable = (msg_rect.r_height - 60) / 20;
  1525. X
  1526. X    if (count < 0 && start_cnt + count < 0) {
  1527. X    print("At the beginning");
  1528. X    return;
  1529. X    } else if (count && start_cnt + count + total_displayable > total_opts) {
  1530. X    print("At the end");
  1531. X    return;
  1532. X    }
  1533. X    start_cnt += count;
  1534. X    if (!msg_pix) {
  1535. X    register int x = (total_opts+1) * 20;
  1536. X    if (x < msg_rect.r_height)
  1537. X        x = msg_rect.r_height;
  1538. X    if (!(msg_pix = mem_create(msg_rect.r_width, x, 1))) {
  1539. X        error("mem_create");
  1540. X        return;
  1541. X    }
  1542. X    pr_rop(msg_pix,0,0, msg_rect.r_width-1, x-1, PIX_CLR,0,0,0);
  1543. X    for (count = 0; count < total_opts; count++)
  1544. X        option_line(count);
  1545. X    }
  1546. X    pw_rop(msg_win, 0, 50, msg_rect.r_width - 1, msg_rect.r_height - 50,
  1547. X       PIX_SRC, msg_pix, 0, start_cnt * 20);
  1548. X}
  1549. X
  1550. Xvoid
  1551. Xtoggle_opt(line)
  1552. X{
  1553. X    register char *p = viewopts[start_cnt+line].v_prompt;
  1554. X
  1555. X    if (do_set(set_options, viewopts[start_cnt+line].v_opt))
  1556. X    un_set(&set_options, viewopts[start_cnt+line].v_opt);
  1557. X    else {
  1558. X    if (p) {
  1559. X        txt.x = 5 + 40 * l_width(DEFAULT) +
  1560. X            (1 + strlen(p) - (*p=='-')) * l_width(DEFAULT);
  1561. X        txt.y = 50 + line*20 + l_height(curfont);
  1562. X    }
  1563. X    if (!p || *p == '-') {
  1564. X        register char *argv[2];
  1565. X        argv[0] = viewopts[start_cnt+line].v_opt;
  1566. X        argv[1] = NULL;
  1567. X        (void) add_option(&set_options, argv);
  1568. X    }
  1569. X    }
  1570. X    option_line(line);
  1571. X    display_opts(0);
  1572. X    if (txt.x > 5)
  1573. X    pw_char(msg_win, txt.x, txt.y, PIX_SRC, fonts[DEFAULT], '_');
  1574. X}
  1575. X
  1576. Xvoid
  1577. Xhelp_opt(line)
  1578. X{
  1579. X    print(viewopts[start_cnt+line].v_description);
  1580. X}
  1581. X
  1582. Xadd_opt(p, line)
  1583. Xregister char *p;
  1584. X{
  1585. X    char buf[80], **argv;
  1586. X    int argc, save_bang = ison(glob_flags, IGN_BANG);
  1587. X
  1588. X    (void) sprintf(buf, "set %s=\"%s\"", viewopts[start_cnt+line].v_opt, p);
  1589. X    turnon(glob_flags, IGN_BANG);
  1590. X    if (argv = make_command(buf, DUBL_NULL, &argc))
  1591. X    (void) do_command(argc, argv, msg_list);
  1592. X    if (!save_bang)
  1593. X    turnoff(glob_flags, IGN_BANG);
  1594. X    option_line(line); /* make sure new value is entered into database */
  1595. X}
  1596. X
  1597. Xoption_line(count)
  1598. Xregister int count;
  1599. X{
  1600. X    register char *p, *v = do_set(set_options, viewopts[start_cnt+count].v_opt);
  1601. X    struct pr_prpos win;
  1602. X
  1603. X    win.pr = msg_pix;
  1604. X    win.pos.y = (start_cnt + count) * 20 + 16;
  1605. X    win.pos.x = 5;
  1606. X
  1607. X    pf_text(win, PIX_SRC, fonts[DEFAULT], blank);
  1608. X    pf_text(win, PIX_SRC, fonts[DEFAULT], viewopts[start_cnt+count].v_opt);
  1609. X    win.pos.x = twenty+20;
  1610. X
  1611. X    if (!(p = viewopts[start_cnt+count].v_prompt) || *p == '-') {
  1612. X    pr_rop(msg_pix, twenty, win.pos.y-10, 16, 16, PIX_SRC, &cycle, 0, 0);
  1613. X    pf_text(win, PIX_SRC, fonts[DEFAULT], (v)? "TRUE  ": "FALSE");
  1614. X    win.pos.x++;
  1615. X    pf_text(win, PIX_SRC, fonts[DEFAULT], (v)? "TRUE  ": "FALSE");
  1616. X    }
  1617. X    if (p) {
  1618. X    if (*p == '-')
  1619. X        p++;
  1620. X    win.pos.x = forty;
  1621. X    /* heighlight */
  1622. X    pf_text(win, PIX_SRC, fonts[DEFAULT], p);
  1623. X    win.pos.x++;
  1624. X    pf_text(win, PIX_SRC, fonts[DEFAULT], p);
  1625. X        win.pos.x = forty + strlen(p) * l_width(DEFAULT);
  1626. X    pf_text(win, PIX_SRC, fonts[DEFAULT], ":");
  1627. X    if (v) {
  1628. X        win.pos.x += (2 * l_width(DEFAULT));
  1629. X        pf_text(win, PIX_SRC, fonts[DEFAULT], v);
  1630. X    }
  1631. X    }
  1632. X}
  1633. X
  1634. X#endif SUNTOOL
  1635. X
  1636. X/*
  1637. X * return a string describing a variable.
  1638. X * parameters: count, str, buf.
  1639. X * If str != NULL, check str against ALL variables
  1640. X * in viewopts array.  The one that matches, set count to it and 
  1641. X * print up all the stuff from the viewopts[count] into the buffer
  1642. X * space in "buf" and return it.
  1643. X */
  1644. Xchar *
  1645. Xvariable_stuff(count, str, buf)
  1646. Xregister char *str, buf[];
  1647. X{
  1648. X    if (str)
  1649. X    for (count = 0; count < total_opts; count++)
  1650. X        if (!strcmp(str, viewopts[count].v_opt))
  1651. X        break;
  1652. X    if (count >= total_opts) {
  1653. X    (void) sprintf(buf, "%s: Not a default %s variable.",
  1654. X               str? str : itoa(count), prog_name);
  1655. X    return NULL;
  1656. X    }
  1657. X    return sprintf(buf, "%12.12s: %s",
  1658. X    viewopts[count].v_opt, viewopts[count].v_description);
  1659. X}
  1660. END_OF_FILE
  1661. if test 12717 -ne `wc -c <'viewopts.c'`; then
  1662.     echo shar: \"'viewopts.c'\" unpacked with wrong size!
  1663. fi
  1664. # end of 'viewopts.c'
  1665. fi
  1666. echo shar: End of archive 12 \(of 12\).
  1667. cp /dev/null ark12isdone
  1668. MISSING=""
  1669. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1670.     if test ! -f ark${I}isdone ; then
  1671.     MISSING="${MISSING} ${I}"
  1672.     fi
  1673. done
  1674. if test "${MISSING}" = "" ; then
  1675.     echo You have unpacked all 12 archives.
  1676.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1677. else
  1678.     echo You still need to unpack the following archives:
  1679.     echo "        " ${MISSING}
  1680. fi
  1681. ##  End of shell archive.
  1682. exit 0
  1683.